﻿package Gameplay.Visualizer
{
	import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.media.Sound;    
    import flash.utils.ByteArray;
    import flash.media.SoundMixer;
	
	public class WheelSoundVisualizer extends AbstractVisualizer 
	{		
		private var FCanvas:BitmapData;
		private var FViewer:Bitmap;
		private var FDraw:Shape;
		private var FParticls:Vector.<Particle>;
		private var FTotal:Number;
		private var FBackground:Shape;
		private var FStep:uint;
		private var FBlur:BlurFilter;
		private var FIntensity:Number;
		
		public function WheelSoundVisualizer() 
		{
			FCanvas = new BitmapData(width, height, true, 0);
			FViewer = new Bitmap(FCanvas);
			FBackground = new Shape();	
			FDraw = new Shape();			
			FTotal = new Number();
			FIntensity = new Number();
			
			addChild(FBackground);
			addChild(FViewer);
			addChild(FDraw);
			
			FStep = 0x123456;
			FBlur = new BlurFilter(8,8,3);
			Init();
		}
		
		private function Init():void
		{
			FParticls = new Vector.<Particle>();
			
			for ( var i:int = 0; i < 512; i++ )
            {
                var vParticle:Particle = new Particle((i*137.5) % 360);
                vParticle.x = width / 2;
                vParticle.y = height / 2;
                FParticls[FParticls.length] = vParticle;
            }
		}
		
		override protected function OnEnterFrame(e:Event):void
		{
			var i:int;
			var vData:Vector.<Number> = ComputeSpectrum();
			
			FDraw.graphics.clear();									   
			for(i=0; i<FParticls.length; i++)
			{
				FParticls[i].Update( width / 2, height / 2, vData[i], i / FParticls.length, FTotal / 512);
			
                FDraw.graphics.beginFill(0xFFFFFF, Math.min(FParticls[i].alpha, 1));
                FDraw.graphics.drawCircle(FParticls[i].x, FParticls[i].y, 2 + 8 * vData[i]);
                FDraw.graphics.endFill();
            }
			
			var vTransformation:ColorTransform = new ColorTransform();
            vTransformation.color = FStep;
			vTransformation.redMultiplier = FTotal / 256;
			
			if(FStep < 0xFFAABB)
			{
				FStep += 128;
			}
			else
			{
				if (FStep > 0x123456)
				{
					FStep -= 128;
				}
			}
			
            FCanvas.draw(FDraw, null, vTransformation);
            FCanvas.applyFilter(FCanvas, FCanvas.rect, new Point(), FBlur);
		}
		
		private function ComputeSpectrum(): Vector.<Number>
		{
			var i:int;
			FTotal = 0;
            var vBuffer: Vector.<Number> = new Vector.<Number>(512);
			var vBytes:ByteArray = new ByteArray;			
			SoundMixer.computeSpectrum(vBytes, true);
            vBytes.position = 0;
            for (i = 0; i < 512; i++)
			{
				vBuffer[i] = vBytes.readFloat();
				FTotal += vBuffer[i];
			}
			
			return vBuffer;
		}
	}	
}
